import java.util.ArrayList;

public class TablaTipos
{
    public ArrayList<Tipo> tabla;

/**
 * Constructor de la tabla de tipos, añade los tipos básicos entero, real y booleano
 */
    public TablaTipos()
    {
        tabla = new ArrayList<Tipo>();

        Tipo t1 = new Tipo("entero", null, null, 1, null);
        Tipo t2 = new Tipo("real", null, null, 1, null);
        Tipo t3 = new Tipo("booleano", null, null, 1, null);

        tabla.add(t1);
        tabla.add(t2);
        tabla.add(t3);
    }

    /**
     * Desrreferencia una fila de la tabla de simbolos
     * @param tipo Fila que se quiere desrreferenciar
     * @return Tipo al que apunta la fila
     */
    public Integer desRef( int tipo )
    {
        if ( tipo < 3 )
            return null;
        else if ( tabla.size() <= tipo )
            return null;
        else
        {
            return tabla.get(tipo).getTipoBase();
        }
    }

    /**
     * Añade un nuevo tipo a la tabla de tipos
     * @param tipo Tipo base de datos que almacena el vector
     * @param aridad Dimensiones del vector
     * @return Devuelve la fila en la que se almacena la última referencia del vector
     */
    public Integer add( Integer tipo, Integer aridad )
    {
        int anterior = tipo;
        if ( aridad != 0 )
        {
            for ( int i = 0; i < aridad; i++)
            {
                Tipo t = new Tipo("vector", null, null, 0, anterior);
                tabla.add(t);
                anterior = tabla.size() - 1;
            }
        }


        return anterior;
    }

    /**
     * Obtiene el tipo que se encuentra en una posición determinada de la tabla
     * @param indice Indice que se quiere conocer
     * @return Tipo del elemento indice
     */
    public Tipo get( int indice )
    {
        if ( tabla!= null && tabla.size() > indice )
            return tabla.get(indice);
        else
            return null;
    }

    public boolean isArray( int tipo )
    {
        return ( tipo > 2 );
    }

    public Integer getTamanyo( Integer tipo )
    {
        Tipo t = get(tipo);

        if ( t.getTipoBase() == null )
            return Tipo.ERROR;

        int size = t.getTamanyo();
        Integer tBase = t.getTipoBase();
        t = get(tBase);
        tBase = t.getTipoBase();

        while ( tBase != null  )
        {
            size *= t.getTamanyo();
            tBase = t.getTipoBase();
            if ( tBase != null )
                t = get(tBase);
        }

        return size;
    }

    public Integer getTipoBase( Integer tipo )
    {
        Tipo t = get(tipo);
        Integer tBase = t.getTipoBase();
        
        while ( tBase != null  )
        {
            t = get(tBase);
            tBase = t.getTipoBase();
        }
        return t.getTipo( t.getTipo() );
    }
}

